package cn.z2huo.demo.mybatis.plus.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.StrUtil;
import cn.z2huo.demo.mapper.user.UserMapper;
import cn.z2huo.demo.model.dataobject.user.UserDO;
import cn.z2huo.demo.mybatis.plus.model.dto.user.curd.SelectListUserDTO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.util.List;
import java.util.Map;

/**
 * <p>DAO层的增删改查削测试
 */
@Slf4j
@Service
public class CURDServiceImpl {

    public static final LocalDate VALID_DATE = LocalDate.of(2020, 1, 1);

    public static final LocalDate INVALID_DATE = LocalDate.of(2077, 1, 1);

    @Autowired
    private UserMapper userMapper;

    /**
     * 查询列表
     */
    public void selectList(SelectListUserDTO dto) {
        List<UserDO> UserDOList = userMapper.selectList(getQueryWrapper(dto));
        log.info("selectList Test, UserDOList = {}", UserDOList);

        List<Map<String, Object>> mapList = userMapper.selectMaps(getQueryWrapper(dto));
        log.info("selectMaps Test, mapList = {}", mapList);
    }

    /**
     * 分页查询列表
     */
    public void selectListPage(SelectListUserDTO dto) {
        List<UserDO> UserDOPageList = userMapper.selectList(new Page<>(1, 2), getQueryWrapper(dto));
        log.info("selectList Page Test, UserDOList = {}", UserDOPageList);

        List<Map<String, Object>> mapList = userMapper.selectMaps(new Page<>(1, 2), getQueryWrapper(dto));
        log.info("selectMaps Page Test, UserDOList = {}", mapList);
    }

    /**
     * 分页查询
     */
    public void selectPage(SelectListUserDTO dto) {
        IPage<UserDO> selectPageResult = userMapper.selectPage(new Page<>(1, 2), getQueryWrapper(dto));
        log.info("selectPage Test, currentPage = {}, pageCount = {}, record per page = {}, total record = {}, records = {}",
                selectPageResult.getCurrent(), selectPageResult.getPages(), selectPageResult.getSize(),
                selectPageResult.getTotal(), selectPageResult.getRecords());

        IPage<UserDO> selectPageResult2 = userMapper.selectPage(new Page<>(2, 2), getQueryWrapper(dto));
        log.info("selectPage Test, currentPage = {}, pageCount = {}, record per page = {}, total record = {}, records = {}",
                selectPageResult2.getCurrent(), selectPageResult2.getPages(), selectPageResult2.getSize(),
                selectPageResult2.getTotal(), selectPageResult2.getRecords());

        IPage<Map<String, Object>> selectMapsPageResult
                = userMapper.selectMapsPage(new Page<>(1, 2), getQueryWrapper(dto));
        log.info("selectMapsPage Test, currentPage = {}, pageCount = {}, record per page = {}, total record = {}, records = {}",
                selectMapsPageResult.getCurrent(), selectMapsPageResult.getPages(), selectMapsPageResult.getSize(),
                selectMapsPageResult.getTotal(), selectMapsPageResult.getRecords());
        if (CollectionUtil.isNotEmpty(selectMapsPageResult.getRecords())) {
            log.info("records class is {}, records element class is {}", selectMapsPageResult.getRecords().getClass(), selectMapsPageResult.getRecords().getFirst().getClass());
        }
    }

    /**
     * 查询一条数据
     */
    public void selectOne(SelectListUserDTO dto) {
        UserDO UserDO = userMapper.selectOne(null, false);
        log.info("selectOne Test, UserDO = {}", UserDO);
        UserDO UserDO2 = userMapper.selectOne(null);
        log.info("selectOne Test, UserDO = {}", UserDO2);
    }

    /**
     * 根据id查询单条记录
     */
    public void selectById(Long id) {
        UserDO UserDO = userMapper.selectById(id);
        log.info("selectById Test, UserDO = {}", UserDO);
    }

    /**
     * 根据id列表查询多条记录
     */
    public void selectByIdList(List<Long> idList) {
        List<UserDO> UserDOList = userMapper.selectBatchIds(idList);
        log.info("selectByIdList Test, UserDOList = {}", UserDOList);
    }

    /**
     * 将map作为查询条件进行查询
     */
    public void selectByMap(Map<String, Object> map) {
        List<UserDO> UserDOList = userMapper.selectByMap(map);
        log.info("selectByMap Test, UserDOList = {}", UserDOList);
    }

    /**
     * 获取查询结果的第一个字段
     */
    public void selectObjs(SelectListUserDTO dto) {
        QueryWrapper<UserDO> queryWrapper = getQueryWrapper(dto);
        queryWrapper.select("user_code", "id");
        List<String> userCodeList = userMapper.selectObjs(queryWrapper);
        log.info("selectObjs Test, userCodeList = {}", userCodeList);
    }

    /**
     * 插入和新增
     */
    public void cudTest() {
        UserDO userDO = new UserDO();
        userDO.setUserCode("71403112");
        userDO.setUserName("test user " + UUID.fastUUID().toString(true));
        // insert 成功之后会给PO对象的id赋值，前提是PO对象中的id为空，如果不为空的话，插入到数据库中的值即为对象中id属性的值
        userMapper.insert(userDO);
        log.info("insert new user, id is {}", userDO.getId());

        userDO.setValidDate(VALID_DATE);
        UpdateWrapper<UserDO> updateWrapper = Wrappers.update();
        updateWrapper.lambda().eq(UserDO::getId, userDO.getId());
        userMapper.update(userDO, updateWrapper);

        userDO.setValidDate(LocalDate.now());
        userDO.setInvalidDate(INVALID_DATE);
        userMapper.updateById(userDO);

        UpdateWrapper<UserDO> updateWrapper2 = Wrappers.update();
        updateWrapper2.lambda().set(UserDO::getValidDate, null).set(UserDO::getValidDate, null)
                .set(UserDO::getInvalidDate, null)
                .set(UserDO::getCompanyCode, "")
                .set(UserDO::getDepartmentCode, "")
                .eq(UserDO::getId, userDO.getId());
        userMapper.update(updateWrapper2);
    }

    public void delete() {
        UserDO userDO = new UserDO();
        userDO.setUserCode("71403112");
        userDO.setUserName("test user " + UUID.fastUUID().toString(true));
        userMapper.insert(userDO);
        userMapper.deleteById(userDO.getId());

        UserDO UserDO2 = new UserDO();
        UserDO2.setUserCode("71403112");
        UserDO2.setUserName("test user " + UUID.fastUUID().toString(true));
        userMapper.insert(UserDO2);
        userMapper.deleteById(UserDO2);

        // 上面UserDO和UserDO2的id属性在第一次新增的时候即复制，之后再用原有对象执行插入操作，插入的id，还为第一次新增所赋的值
        userMapper.insert(userDO);
        userMapper.insert(UserDO2);
        userMapper.deleteBatchIds(List.of(userDO.getId(), UserDO2.getId()));

        userMapper.insert(userDO);
        QueryWrapper<UserDO> queryWrapper = Wrappers.query();
        queryWrapper.lambda().eq(UserDO::getId, userDO.getId());
        userMapper.delete(queryWrapper);

        userMapper.insert(userDO);
        userMapper.deleteByMap(Map.of("id", userDO.getId()));
    }

    private QueryWrapper<UserDO> getQueryWrapper(SelectListUserDTO dto) {
        QueryWrapper<UserDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.like(StrUtil.isNotEmpty(dto.getUserCode()), "user_code", dto.getUserCode());
        queryWrapper.like(StrUtil.isNotEmpty(dto.getUserName()), "user_name", dto.getUserName());
        queryWrapper.eq(StrUtil.isNotEmpty(dto.getCompanyCode()), "company_code", dto.getCompanyCode());
        queryWrapper.eq(StrUtil.isNotEmpty(dto.getDepartmentCode()), "department_code", dto.getDepartmentCode());
        queryWrapper.lt(dto.getDate() != null, "valid_date", dto.getDate());
        queryWrapper.gt(dto.getDate() != null, "invalid_date", dto.getDate());
        return queryWrapper;
    }

    private QueryWrapper<UserDO> getQueryWrapper2(SelectListUserDTO dto) {
        QueryWrapper<UserDO> queryWrapper = new QueryWrapper<>();
        return null;
    }

}
